/*
 * @Description: 分段选择控制器
 * @Author: skj
 * @Date: 2019-08-27 15:24:06
 * @LastEditors: skj
 * @LastEditTime: 2019-08-30 14:10:09
 */
import React, {Component} from "react";
import {
	View,
	StyleSheet,
	ScrollView,
	Text,
	Dimensions,
	TouchableWithoutFeedback,
	Animated,
	Easing,
	ViewPropTypes,
	StyleProp,
	TextStyle
} from "react-native";
import PropTypes from "prop-types";
import Device from "@greens/device/src/device";

const SCREEN = Dimensions.get("window");
export default class SegmentBar extends Component {
	constructor(props) {
		super(props);
		this.state = {
			evently: false,
			isMoving: false, //scrollview是否正在滚动
			titles: props.titles || [],
			indicatorOffsetX: new Animated.Value(0), //滑动指示器X轴偏移
			indicatorWidth: new Animated.Value(0), //滑动指示器宽度变化
			currentIndex: props.initSelectedIndex
		};
		this.scrollview;
		this.contentOffset = {x: 0, y: 0}; //scrollView当前偏移量
		this.contentSize = {x: 0, y: 0, width: SCREEN.width, height: 0}; //scrllView constentSize
		this.itemsMap = new Map(); //存储item size
	}

	componentWillReceiveProps(props) {
		this.setState({
			titles: props.titles
		});
	}

	componentDidMount() {
	}

	/**
	 * @description:scrollToIndex 移动到指定index
	 * @param {Number} index
	 * @param {Boolean} animated 是否有动画
	 * @return:
	 */
	scrollToIndex = (index, animated = true) => {
		this.setState({
			currentIndex: index
		});
		let {lineWidthScale} = this.props;
		if (lineWidthScale <= 0 || lineWidthScale > 1) {
			lineWidthScale = 0.6;
		}
		const rect = this.itemsMap.get(index);
		let indicatorWidth = lineWidthScale * rect.width;
		let indicatorOffsetX = rect.x + (rect.width - indicatorWidth) / 2.0;
		Animated.parallel([
			Animated.timing(
				this.state.indicatorWidth, // The value to drive
				{
					toValue: indicatorWidth,
					duration: 0,
					easing: Easing.linear // Animate to final value of 1
				}
			),
			Animated.timing(
				// Animate value over time
				this.state.indicatorOffsetX, // The value to drive
				{
					toValue: indicatorOffsetX,
					duration: animated ? 100 : 0,
					easing: Easing.linear // Animate to final value of 1
				}
			)
		]).start();
		if (this.state.evently == true || this.contentSize.width <= SCREEN.width) return;
		//1.计算当前item中心点的位置
		let itemCenterX = rect.x + rect.width / 2.0;
		//2.计算item中心点相对于屏幕中心点距离差
		let relativeX = SCREEN.width / 2.0 - itemCenterX;
		if (relativeX > 0) {
			this.scrollview.scrollTo({x: 0, y: 0, animated: animated});
		} else if (relativeX < 0) {
			//1.计算剩余可左移长度,
			let rest = parseInt(this.contentSize.width - this.contentOffset.x - SCREEN.width);
			//2.计算item需要移动的距离
			let dValue = parseInt(SCREEN.width / 2.0 - itemCenterX + this.contentOffset.x);
			//3.计算可移动长度-需要移动的长度,如果大于0则还有大于当前item中心点的可移动长度
			let moveX = rest + dValue;
			// alert(this.contentOffset.x + "dValue" + dValue + "rest:" + rest + "contentSize" + this.contentSize.width);
			if (moveX > 0) {
				let actualOffsetX = Math.abs(dValue - this.contentOffset.x);
				this.scrollview.scrollTo({x: actualOffsetX, y: 0, animated: animated});
			} else {
				this.scrollview.scrollToEnd({animated: animated});
			}
		}
	};
	//处理初始化tab Index 事件
	handleInitTabSelectedEvent = () => {
		let {initSelectedIndex, lineWidthScale, titles} = this.props;
		if (titles && titles.length > 0) {
			if (initSelectedIndex > titles.length) {
				initSelectedIndex = 0
			}
			const rect = this.itemsMap.get(initSelectedIndex);
			if (rect) {
				this.setState({
					indicatorWidth: new Animated.Value(rect.width * lineWidthScale),
					indicatorOffsetX: new Animated.Value(rect.x + (rect.width * (1 - lineWidthScale)) / 2.0) //滑动指示器X轴偏移
				});
				this.scrollToIndex(initSelectedIndex, false);
			} else {
				console.log('布局计算错误')
			}
		}
	};
	/**
	 * @description: getSubItem 获取item
	 * @param {String} title 标题
	 * @param {number} index 索引
	 * @return:
	 */
	getSubItem = (title, index) => {
		const {evently, titles, currentIndex} = this.state;
		let {selectItemStyle, normalItemStyle, initSelectedIndex, lineWidthScale} = this.props;
		return (
			<TouchableWithoutFeedback
				key={index}
				onPress={() => {
					this.scrollToIndex(index);
					this.props.onTabSelected && this.props.onTabSelected(index);
				}}
				onLayout={e => {
					let rect = e.nativeEvent.layout;
					this.itemsMap.set(index, rect);
					if (index == initSelectedIndex) {
						this.handleInitTabSelectedEvent();
					}
				}}
			>
				<View style={[styles.item_baseStyle, evently && {width: SCREEN.width / titles.length}]}>
					<Text style={[styles.item_sub_style, currentIndex == index ? [styles.selectItemStyle,selectItemStyle] : normalItemStyle]}>
						{title}
					</Text>
				</View>
			</TouchableWithoutFeedback>
		);
	};
	layoutItems = () => {
		const {titles} = this.state;
		if (!titles || titles.length <= 0) return;
		let items = [];
		for (let i = 0; i < titles.length; i++) {
			let title = titles[i];
			let item = this.getSubItem(title, i);
			items.push(item);
		}
		return items;
	};
	/**
	 * @description: onAnimationEnd 监听scrollView滚动结束,记录偏移量
	 * @param {type}
	 * @return:
	 */
	onAnimationEnd = e => {
		this.contentOffset = e.nativeEvent.contentOffset;
	};
	/**
	 * @description: 监听scrollview contentSize 变化结束
	 * @return:
	 */
	observeContentSizeChange = (width, height) => {
		this.contentSize = {width: width, height: height};
		if (width > SCREEN.width) {
			this.setState({
				evently: false
			});
		} else {
			this.setState({
				evently: true
			});
		}
		this.handleInitTabSelectedEvent();
	};

	render() {
		const {lineColor, lineHeight, showBottomLine, containerStyle} = this.props;
		return (
			<View style={[styles.container, containerStyle]}>
				<ScrollView
					ref={view => (this.scrollview = view)}
					horizontal
					scrollEventThrottle={0}
					showsHorizontalScrollIndicator={false}
					bounces={false}
					onMomentumScrollEnd={this.onAnimationEnd}
					onScrollEndDrag={this.onAnimationEnd}
					onContentSizeChange={this.observeContentSizeChange}
				>
					<View>
						<View style={{flexDirection: "row", flex: 1}}>{this.layoutItems()}</View>
						<Animated.View
							View
							style={{
								backgroundColor: lineColor,
								height: lineHeight,
								width: this.state.indicatorWidth,
								transform: [{translateX: this.state.indicatorOffsetX}]
							}}
						/>
						{showBottomLine && <View style={styles.lineStyle}></View>}
					</View>
				</ScrollView>
			</View>
		);
	}
}
SegmentBar.propTypes = {
	containerStyle: ViewPropTypes.style,
	titles: PropTypes.array.isRequired,
	normalItemStyle: PropTypes.oneOfType([Text.propTypes.style, ViewPropTypes.style]),
	selectItemStyle: PropTypes.oneOfType([Text.propTypes.style, ViewPropTypes.style]),
	lineColor: PropTypes.string,
	lineHeight: PropTypes.number,
	lineWidthScale: PropTypes.number, //0~1.0
	onTabSelected: PropTypes.func,
	showBottomLine: PropTypes.bool, //底部分割线
	initSelectedIndex: PropTypes.number //初始化时选中的index
};
SegmentBar.defaultProps = {
	lineColor: "#2780FF",
	lineHeight: 3,
	lineWidthScale: 0.6,
	showBottomLine: false,
	initSelectedIndex: 0
};
const styles = StyleSheet.create({
	container: {
		backgroundColor: "#ffffff",
		height: 45
	},
	selectItemStyle: {
		color: "#E83C36"
	},
	item_baseStyle: {
		justifyContent: "center",
		alignItems: "center"
	},
	item_sub_style: {
		fontSize: 15,
		color: "#222222",
		alignSelf: "center",
		marginHorizontal: 15
	},
	lineStyle: {
		height: Device.isIOS ? 0.5 : 1,
		backgroundColor: "rgb(231,231,231)"
	}
});
